﻿using Hangfire;
using Hangfire.Dashboard.BasicAuthorization;
using Hangfire.HttpJob;
using Hangfire.MySql;
using Microsoft.AspNetCore.Builder;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MySqlConnector;
using SqlSugar;
using System.Transactions;
using Zhp.Common.Appsetting;
using Zhp.Common.Extention;
using Zhp.Common.Helper;

namespace Zhp.Common.Hangfire
{
    public static class HangfireExtensions
    {
        public static IServiceCollection AddHangfire(this IServiceCollection services, string dbName = "HangfireConnectString")
        {
            var options = AppSettingHelper.GetOptions<SysDataOptions>();
            var dbType = AppHelper.Configuration.GetConnectionString("DbType").ToEnum<DbType>();
            var connectionString = AppHelper.Configuration.GetConnectionString(dbName);

            if (options.InitDatabase)
            {
                //自动创建数据库
                AutoCreateDataBase(services, dbType, connectionString);
            }

            // Add Hangfire services.
            services.AddHangfire(configuration => 
            { 
                configuration
                    .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
                    .UseSimpleAssemblyNameTypeSerializer()
                    .UseRecommendedSerializerSettings();

                if (dbType == DbType.MySql)
                {
                    configuration.UseStorage(new MySqlStorage(connectionString, new MySqlStorageOptions
                    {
                        TransactionIsolationLevel = IsolationLevel.ReadCommitted,
                        QueuePollInterval = TimeSpan.FromSeconds(15),
                        JobExpirationCheckInterval = TimeSpan.FromHours(1),
                        CountersAggregateInterval = TimeSpan.FromMinutes(5),
                        PrepareSchemaIfNecessary = true,
                        DashboardJobListLimit = 50000,
                        TransactionTimeout = TimeSpan.FromMinutes(1),
                        TablesPrefix = "Hangfire"
                    }));
                }
                else if (dbType == DbType.SqlServer)
                {
                    configuration.UseSqlServerStorage(connectionString);
                }

                configuration.UseHangfireHttpJob();

            });

            // Add the processing server as IHostedService
            services.AddHangfireServer();

            ConsoleHelper.WriteLine($"Hangfire服务注入成功", ConsoleColor.Green);

            return services;
        }

        /// <summary>
        /// 自动创建数据库
        /// </summary>
        /// <param name="services"></param>
        /// <param name="connectionString"></param>
        private static void AutoCreateDataBase(IServiceCollection services, DbType dbType, string connectionString)
        {
            string databaseName = string.Empty;
            if (dbType == DbType.MySql)
            {
                var builder = new MySqlConnectionStringBuilder(connectionString);
                databaseName = builder.Database;
            }
            else if (dbType == DbType.SqlServer)
            {
                var builder = new SqlConnectionStringBuilder(connectionString);
                databaseName = builder.InitialCatalog;
            }

            var db = services.BuildServiceProvider().GetService<ISqlSugarClient>();
            bool flag = db.DbMaintenance.CreateDatabase(databaseName, null);
            if (flag)
            {
                ConsoleHelper.WriteLine($"Hangfire数据库创建成功", ConsoleColor.Green);
            }
        }

        public static void UseHangfire(this IApplicationBuilder app)
        {
            app.UseHangfireDashboard("/hangfire", new DashboardOptions()
            {
                 Authorization = new[]
                 {
                     new BasicAuthAuthorizationFilter(new BasicAuthAuthorizationFilterOptions
                     {
                         RequireSsl = false, // 是否需要SSL连接
                         SslRedirect = false, // 是否进行SSL重定向
                         LoginCaseSensitive = true, // 是否区分大小写
                         Users = new []
                         {
                             new BasicAuthAuthorizationUser
                             {
                                  Login = "zhp",
                                  PasswordClear = "123456"
                             }
                         }
                     })
                 }
            });
        }
    }
}
